<template>
<div class="row">
  <div class="col-md-12">
    <my-navbar fixed="top">
      <template slot="left"> 
        <connect-server 
          @ev-connected="onConnected" 
          @ev-disconnected="onDisconnected">
        </connect-server>                            
      </template> 
      <template slot="right" v-if="!inControl"> 
        <select class="form-control" v-model="topoId">
          <option v-for="option in topoDevs" :value="option.topoId">{{option.devName}}</option>
        </select>
        <button class="btn btn-default" @click.prevent="onStartControl">{{$t("common.start")}}</button>
      </template> 
      <template slot="right" v-if="inControl"> 
        <button class="btn btn-default" @click.prevent="onStopControl">{{$t("common.stop")}}</button>
      </template>     
    </my-navbar>
  </div>
</div>
</template>

<script>
import _ from 'lodash'
import toast from 'libs/toast.js'
import store from 'share/server/vuex/store.js'
import {makeUri, newWebsocket} from 'share/server/api.js'
import ConnectServer from 'share/server/components/ConnectServer.vue'
import screenfull from 'screenfull'

export default {
  store,
  components: {
    'connect-server': ConnectServer
  },
  vuex: {
    getters: {
      topoSummary: (state) => state.devmng.topoSummary
    }
  },
  computed: {
    topoDevs () {
      return _.filter(this.topoSummary.list, (item) => {
        return item.devType === 'encoder'
      })
    }
  },
  data () {
    return {
      connect: false,
      inControl: false,
      topoId: -1
    }
  },
  methods: {
    sendCmd (action, paramlist) {
      //console.log(action + ':' + JSON.stringify(paramlist))
      if (this.ws) {
        let req = {
          action,
          paramlist
        }
        this.ws.send(JSON.stringify(req))
      }
    },
    onMouseUpOrDown (e) {
      if (this.inControl) {
        let action = e.type === 'mouseup' ? 'mouseUp' : 'mouseDown'
        let buttonNames = ['ButtonLeft', 'ButtonMiddle', 'ButtonRight']
        this.sendCmd(action, {
          buttonName: buttonNames[e.button],
        })  
      }
    },
    onMouseMove (e) {
      if (this.inControl) {
        this.movementX += e.movementX
        this.movementY += e.movementY
        if (Math.abs(this.movementX) > 1 || Math.abs(this.movementY) > 1) {
          //console.log(this.movementX + ' ' + this.movementY)
          this.sendCmd('mouseRelMove', {
            dx: this.movementX,
            dy: this.movementY,
          })
          this.movementX = 0
          this.movementY = 0
        }
      }
    },
    onMouseWheel (e) {
      if (this.inControl) {
        e.preventDefault()
        this.sendCmd('mouseWheel', {
          dy: e.wheelDeltaY ? e.wheelDeltaY : e.detail
        })         
      }     
    },
    isRepeatedKey (e) {
      let keyHistory = this.keyRecord[e.code]
      if ((keyHistory) 
        && (keyHistory.type === e.type)) {
        keyHistory.cnt++
        return true
      } else {
        this.keyRecord[e.code] = {
          type: e.type,
          cnt: 0
        }
        return false
      }
    },
    onKeyUpOrDown (e) {
      if (this.inControl) {
        e.preventDefault()
        if (!this.isRepeatedKey(e)) {
          let action = e.type === 'keyup' ? 'keyUp' : 'keyDown'
          this.sendCmd(action, {
            keyName: e.code,
          })        
        }        
      }
    },
    onStartControl () {
      if (!this.ws) {
        toast.e(this, this.$t('common.fail'), this.$t('error.notConnected'))
        return
      }

      if (this.topoId < 0) {
        toast.e(this, this.$t('common.fail'), this.$t('error.params'))
        return
      }

      let req = {
        action: 'addKvmConnect',
        paramlist: {
          kvmServerTopoId: this.topoId
        }
      }

      this.ws.send(JSON.stringify(req))
      this.inControl = true
      screenfull.request()
    },
    onStopControl () {
      this.inControl = false
      screenfull.exit()
    },
    connectWs () {
      var ws = newWebsocket('/websocket/kvm')
      ws.onopen = function(e) {
        toast.i(this, 'websocket', 'open success')
      }.bind(this)
      ws.onmessage = function(e) {
        toast.i(this, 'websocket', e.data)
      }.bind(this)
      ws.onclose = function(e) {
        toast.i(this, 'websocket', 'close ' + e.data)
      }.bind(this)
      ws.onerror = function(e) {
        toast.i(this, 'websocket', 'error ' + e.data)
      }.bind(this)
      this.ws = ws      
    },
    disconnectWs () {
      if (this.ws) {
        this.ws.close()
        this.ws = null       
      }
    },
    onDisconnected () {
      this.disconnectWs()
      this.onStopControl()
      this.connect = false
    },
    onConnected () {
      this.connect = true
      if (this.topoDevs.length > 0) {
        this.topoId = this.topoDevs[0].topoId
      }
      this.connectWs()
    }
  },
  ready () {
    this.movementX = 0
    this.movementY = 0
    this.keyRecord = {}
    document.onkeyup = this.onKeyUpOrDown
    document.onkeydown = this.onKeyUpOrDown
    document.onmousewheel = this.onMouseWheel
    document.onmousemove = this.onMouseMove
    document.onmouseup = this.onMouseUpOrDown
    document.onmousedown = this.onMouseUpOrDown
    if (document.addEventListener) {
      document.addEventListener('DOMMouseScroll', this.onMouseWheel, false)
    }
    document.oncontextmenu = function() { return false }
  }
}
</script>

<style>
body { 
  padding-top: 70px;
  cursor: default;
}
.fixed-height {
  max-height: 800px;
  overflow-x: hidden;
  overflow-y: auto;
}
</style>